package com.test.web3j;
 
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.message.BasicHeader;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.test.web3j.util.HttpUtil;
 
/**
 * usdt操作
 **/
public class UsdtService {
 
    private String address = "myV2jo7tX2oWjmHmKRe3Wprbekpe1nPtFX";
    private int propertyid = 1;
	private  String url = "http://127.0.0.1:8332";
	private String username = "guwq";
	private String password = "6gKAgrJv8CQr2CGUhjVbBFLSj29HnE6YGXvfykHJzS3k";
 
    private final static String RESULT = "result";
    private final static String METHOD_SEND_TO_ADDRESS = "omni_send";
    private final static String METHOD_SEND_TO_ADDRESS1 = "sendtoaddress";
    private final static String METHOD_GET_TRANSACTION = "omni_gettransaction";
    private final static String METHOD_GET_BLOCK_COUNT = "getblockcount";
    private final static String METHOD_NEW_ADDRESS = "getnewaddress";
    private final static String METHOD_GET_BALANCE = "omni_getbalance";
    private final static String METHOD_GET_LISTBLOCKTRANSACTIONS = "omni_listblocktransactions";
    private final static String METHOD_GET_ADDRESS_BY_ACCOUNT = "getaddressesbyaccount";
	private static final String METHOD_GET_ACCOUNT = "getaccount";
    
    
    //前四个参数在USDT钱包conf文件中设置
    //钱包密码PASSWORD打开钱包后设置的密码
 
    /***
     * 取得钱包相关信息
     * 若获取失败，result为空，error信息为错误信息的编码
     * */
    public JSONObject getInfo() throws Exception {
    	return doRequest("omni_getinfo");
    }
    
    /**
     * USDT产生地址
     * @return
     */
    public String getNewAddress(){
        JSONObject json = doRequest(METHOD_NEW_ADDRESS);
        if(isError(json)){
            System.out.println("获取USDT地址失败:{}"+json.get("error"));
            return "";
        }
        return json.getString(RESULT);
    }
    
    /**
     * 根据account查询address
     */
    public String[] getAddrByAccount(String account) {
    	JSONObject json = doRequest(METHOD_GET_ADDRESS_BY_ACCOUNT, account);
        if(isError(json)){
            System.out.println("获取USDT地址失败:{}"+json.get("error"));
            return null;
        }
        JSONArray jsonArr = json.getJSONArray(RESULT);
        Object[] objArr = jsonArr.toArray();
        String[] addrArr = new String[objArr.length];
        int i = 0;
        for(Object obj : objArr) {
        	addrArr[i] = obj.toString();
        	i++;
        }
    	return addrArr;
    }
    
    /**
     * 通过address获取account
     * @param address
     * @return 如果account为空，则返回空字符串
     */
    public String getAccountByAddr(String address) {
        JSONObject json = doRequest(METHOD_GET_ACCOUNT, address);
        if(isError(json)) {
        	System.out.println("getAccountByAddr | 通过address获取account发生错误error:{}" + json.get("error"));
            return null;
        }
        
        String account = json.getString(RESULT);
        System.out.println("getAccountByAddr | 通过address获取account成功。account:{}" + account);
        return account;
    }
 
    /**
     * USDT查询余额
     * @return
     */
    public double getBalance(){
        JSONObject json = doRequest(METHOD_GET_BALANCE,address,propertyid);
        if(isError(json)){
            System.out.println("获取USDT余额:{}"+json.get("error"));
            return 0;
        }
        System.out.println(json.toJSONString());
        return json.getJSONObject(RESULT).getDouble("balance");
//        return json.getBigDecimal(RESULT).doubleValue();
//        return BigDecimalUtil.inputConvert(json.getJSONObject(RESULT).getDouble("balance"));
    }
 
    /**
     * USDT转帐
     * @param addr
     * @param value
     * @return
     */
    public String send(String addr, double amt){
        if(vailedAddress(addr)){
//            double amt = BigDecimalUtil.outputConvert(value);
            JSONObject json = doRequest(METHOD_SEND_TO_ADDRESS,address,addr,propertyid,String.valueOf(amt));
            if(isError(json)){
                System.out.println("USDT 转帐给 "+addr+" value:"+amt+"  失败 ："+json.get("error"));
                return "";
            }else{
                System.out.println("USDT 转币给"+addr+" value:"+amt+"成功");
                return json.getString(RESULT);
            }
        }else{
            System.out.println("USDT接受地址不正确");
            return "";
        }
    }
    
    public String sendToAddress(String addr, double amt){
        if(vailedAddress(addr)){
//            double amt = BigDecimalUtil.outputConvert(value);
            JSONObject json = doRequest(METHOD_SEND_TO_ADDRESS1,addr,amt);
            if(isError(json)){
                System.out.println("USDT 转帐给 "+addr+" value:"+amt+"  失败 ："+json.get("error"));
                return "";
            }else{
                System.out.println("USDT 转币给"+addr+" value:"+amt+"成功");
                return json.getString(RESULT);
            }
        }else{
            System.out.println("USDT接受地址不正确");
            return "";
        }
    }
 
    /**
     * 验证地址的有效性
     * @param address
     * @return
     * @throws Exception
     */
    public boolean vailedAddress(String address) {
        JSONObject json  = doRequest("validateaddress",address);
        if(isError(json)){
            System.out.println("USDT验证地址失败:"+json.get("error"));
            return false;
        }else{
            return json.getJSONObject(RESULT).getBoolean("isvalid");
        }
    }
 
    /**
     * 区块高度
     * @return
     */
    public int getBlockCount(){
        JSONObject json = null;
        try {
            json = doRequest(METHOD_GET_BLOCK_COUNT);
            if(!isError(json)){
                return json.getInteger("result");
            }else{
                System.out.println(json.toString());
                return 0;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
 
    public boolean parseBlock(int index) {
    	//doRequest("omni_listblocktransactions",279007);
    	//{"result":["63d7e22de0cf4c0b7fd60b4b2c9f4b4b781f7fdb8be4bcaed870a8b407b90cf1","6fb25ab84189d136b95d7f733b0659fa5fbd63f476fb1bca340fb4f93de6c912","d54213046d8be80c44258230dd3689da11fdcda5b167f7d10c4f169bd23d1c01"],"id":"1521454868826"}
        JSONObject jsonBlock = doRequest(METHOD_GET_LISTBLOCKTRANSACTIONS, index);
        if (isError(jsonBlock)) {
            System.out.println("访问USDT出错");
            return false;
        }
        JSONArray jsonArrayTx = jsonBlock.getJSONArray(RESULT);
        if (jsonArrayTx == null || jsonArrayTx.size() == 0) {
            //没有交易
            return true;
        }
        Iterator<Object> iteratorTxs = jsonArrayTx.iterator();
        while(iteratorTxs.hasNext()){
            String txid = (String) iteratorTxs.next();
//            parseTx(txid,null);
        }
        return true;
    }
 
//    public void parseTx(String txid,List<UserCoinAddressEntity> userList){
//    	/**
//    	 *{"result":{"amount":"50.00000000","divisible":true,"fee":"0.00000257",
//    	 *"txid":"f76d51044f156e6ed84c11e6531db1d6d70799196522c07bd2a8870a21f90220","ismine":true,
//    	 *"type":"Simple Send","confirmations":565,"version":0,"sendingaddress":"mh8tV2mfDa6yHK76t68N3paoGdSmangJDi",
//    	 *"valid":true,"blockhash":"000000000000014cdef6ee8a095b58755efebf913b1ab13bb23adaa33b6f7b05",
//    	 *"blocktime":1523528971,"positioninblock":189,"referenceaddress":"mg5yVUSwGNEJNhYKfyETV2udWok6Q4pgLx",
//    	 *"block":1292526,"propertyid":2,"type_int":0},"id":"1523860978684"}
//    	 */
//        JSONObject jsonTransaction = doRequest(METHOD_GET_TRANSACTION, txid);
//        if(isError(jsonTransaction)) {
//            System.out.println("处理USDT tx出错");
//            return;
//        }
//        JSONObject jsonTResult = jsonTransaction.getJSONObject(RESULT);
//        if (!jsonTResult.getBoolean("valid")) {
//        	System.out.println("不是有效数据");
//            return;
//		}
//        int propertyidResult = jsonTResult.getIntValue("propertyid");
//        if (propertyidResult!=propertyid) {
//        	System.out.println("非USDT数据");
//            return;
//		}
//        //int coinfirm = jsonTResult.getIntValue("confirmations");
//        double value = jsonTResult.getDouble("amount");
//        if(value >0) {
//            String address = jsonTResult.getString("referenceaddress");
//            for (UserCoinAddressEntity addressModel : userList) {
//                //如果有地址是分配给用记的地址， 则说明用户在充值
//                if (address.equals(addressModel.getAddress())) {
//                    //添加充值记录
//                	System.out.println("添加用户充值记录");
//                }
//            }
//        }
//    }
 
    private boolean isError(JSONObject json){
        if( json == null || (StringUtils.isNotEmpty(json.getString("error")) && json.get("error") != "null")){
            return true;
        }
        return false;
    }
 
    private JSONObject doRequest(String method,Object... params){
        JSONObject param = new JSONObject();
        param.put("id",System.currentTimeMillis()+"");
        param.put("jsonrpc","2.0");
        param.put("method",method);
        if(params != null){
            param.put("params",params);
        }
        String creb = Base64.encodeBase64String((username+":"+password).getBytes());
        List<Header> headers = new ArrayList<>();
        Header header = new BasicHeader("Authorization", "Basic "+creb);
        headers.add(header);
        String resp = "";
        if (METHOD_GET_TRANSACTION.equals(method)){
            try{
                resp = HttpUtil.doPost(url,headers,param.toJSONString());
            }catch (Exception e){
                if (e instanceof IOException){
                    resp = "{}";
                }
            }
        }else{
            resp = HttpUtil.doPost(url,headers,param.toJSONString());
        }
        return JSON.parseObject(resp);
    }
 
    public static void main(String args[]) throws Exception{
      UsdtService usdtUtils = new UsdtService();
      
      // 查询钱包信息 ok
//      System.out.println(usdtUtils.getInfo());
      
      // 根据account查询address
//      System.out.println(usdtUtils.getAddrByAccount("guwq")[0]);
      
      // 通过address获取account
  	System.out.println(usdtUtils.getAccountByAddr("mkw5A1UuXuQ9uKrAfoEEtsXYHsvRsEFC6i"));
      
      // 创建一个address ok
//      System.out.println(usdtUtils.getNewAddress());
        
      // 查询余额
//      System.out.println(usdtUtils.getBalance());
      
//      // 转账
//      String toAddr = "mn4S2LV3ZB5xDK8hcQEp9hknKwjidYFkqc";
//      System.out.println(usdtUtils.sendToAddress(toAddr, 10.0));
    }
}
